// 导入npm 包封装的WxRequest类
import WxRequest from 'mina-request'
// 导入自己封装的WxRequest类
// import WxRequest from './request'
// 导入封装的本地存储操作模块
import { getStorage, clearStorage } from './storage'
// 导入封装的增强 API
import { toast, modal } from './extendApi'
import { env } from './env'

//------------------------以下是实例化的代码--------------------------------------------------------
//---目前这个文件代码量已经非常非常多了，为了不影响我们后面的代码维护，所以我们把这个文件进行拆分
//目前写到用一个文件中，是为了方便测试，以后会提取多个文件

// //对WxRequest进行实例化===================================================================================================
const instance = new WxRequest({
  // baseURL: 'https://gmall-prod.atguigu.cn/mall-api', // 请求基准地址
  baseURL: env.baseURL,
  timeout: 15000, // 默认的超时时长，小程序默认的超时时长是 1 分钟
  isLoading: false //整个项目都不需要显示`loading` 效果，可以在实例化的时候，传入 `isLoading` 配置为 `false`
})

//如果通过实例配置了拦截器，就会覆盖默认的拦截器
// 添加请求拦截器 (在请求发送之前对请求参数进行新增或者修改)=========================================================
//打印的对象里面有很多是wxRequest默认提供的，其中data才是服务器真正响应的数据，也就是说，这个字段才是公司后端返回的数据，那么我们在进行业务开发时，只需要用data就好了，所以接下来我们需要把data简化后返回，从response中把data也解构出来，如果请求成功，我们把服务器响应的数据data返回就可以
instance.interceptors.request = (config) => {
  // 在实际开发中，有一些接口需要使用访问令牌 token
  // 访问令牌 token 通常是存储到本地
  // 需要先从本地获取到存储的 token
  const token = getStorage('token')

  //在发送请求之前，需要先判断本地是否存在访问令牌token
  // 如果本地存在 token，这时候就需要在请求头中添加 token 字段
  if (token) {
    config.header['token'] = token
  }

  //
  // 在发送请求之前做些什么
  return config
}

// 添加响应拦截器 (在服务器响应数据以后，对返回的数据进行逻辑处理)==========================================================
instance.interceptors.response = async (response) => {
  // 从 response 对象中解构两个数据
  const { isSuccess, statusCode,data } = response

  // response 服务器响应的数据，只不过数据被 wx.request 进行了一层包装
  // console.log(response)

  // response.config 封装的包里面提供的 config 属性，是请求的参数信息
  // 可以使用请求参数进行代码的调试

  // response.data 服务器真正响应的数据

  // response.isSuccess 判断代码执行了哪一个回调函数
  // isSuccess = true，说明代码执行了 wx.request 方法的 success 回调函数
  // isSuccess = false，说明代码执行了 wx.request 方法的 fail 回调函数

  // 如果 isSuccess = false，说明网络出现了问题
  if (!isSuccess) {
    toast({
      title: '网络异常请重试',
      icon: 'error'
    })

    return Promise.reject(response)
  }

  // 如果 isSuccess = true，说明代码执行到了 success 回调函数
  // 需要开发者对返回的参数进行逻辑判断
  // 需要对后端返回的业务状态码进行判断
  // 业务状态码 === 200，接口调用成功，服务器成功返回了数据
  // 业务状态码 === 208，没有 token 或者 token 失效，需要让用户重新进行登录
  // 业务状态码既不等于 200，也不等于 208，说明出现了其他异常，需要给用户统一进行提示
  switch (statusCode) {
    case 200:
      // 接口调用成功，服务器成功返回了数据，只需要将数据简化以后返回即可
      return data

    // 如果返回的业务状态码等于208，说明没有token，或者token失效，
    //就需要让用户登录或者重新登录
    case 208:
      const res = await modal({
        //因为返回的说promise,所以要加一个await
        content: '鉴权失败，请重新登录哈哈哈哈哈哈',
        showCancel: false //不展示取消按钮，必须让用户登录
      })

      if (res) {
        // 既然用户需要重新进行登录，就需要把之前用户存储的信息(过期的 token) 进行清除
        clearStorage()

        //跳转到登录页面
        wx.navigateTo({
          url: '/pages/login/login'
        })
      }

      return Promise.reject(response) //通过Promise.reject抛出异常

    //给用户进行统一提示，如果返回的业务代码，既不等于200也不等于208，就需要给用户统一进行提示
    default:
      toast({
        title: '程序出现异常，请联系<可我不敌可爱~~~~>或稍后重试！'
      })
      return Promise.reject(response) //通过Promise.reject抛出异常
  }

  // return response
}

// 导出实例================================================================================================================
//将WxRequest实例进行暴露出去，方便再其他文件中进行使用
export default instance

//mina-request可用的实例方法。指定的配置将与实例的配置合并。=============================
// instance.request(config)
// instance.get(url, data, config)
// instance.delete(url, data, config)
// instance.post(url, data, config)
// instance.put(url, data, config)
// instance.all(...promise) // 传入一个个 Promise 即可
// instance.upload(url, filePath, name, config) // 将本地资源上传到服务器
